import type { ElasticsearchClient } from "../client";
import {
  BaseSearchProp,
  BaseSearchResult,
  ClusterHealth,
  DataSearchProp,
  DataSearchResult,
  ElasticsearchClientProp,
  IndexItem,
  IndexItemResult,
  Overview,
  SeniorSearchProp
} from "../types";
import type { AxiosRequestConfig } from "axios";

export abstract class ElasticsearchClientHttp implements ElasticsearchClient {
  protected readonly props: ElasticsearchClientProp;

  protected constructor(props: ElasticsearchClientProp) {
    this.props = props;
  }

  protected request(config: AxiosRequestConfig) {
    const headers: Record<string, string> = {
      "Content-Type": "application/json; charset=utf-8"
    };
    if (this.props.is_auth) {
      if (this.props.auth_type === 2) {
        headers[this.props.auth_user] = this.props.auth_password;
      }
      if (this.props.auth_type === 3) {
        headers["Cookie"] = this.props.auth_password;
      } else {
        config.auth = {
          username: this.props.auth_user,
          password: this.props.auth_password
        };
      }
    }
    return this.props.adapter({
      ...config,
      baseURL: this.props.value,
      headers: {
        ...config.headers,
        ...headers
      },
      responseEncoding: "utf-8",
      responseType: "text"
    });
  }

  // ---------------------------------------- 实例操作 ----------------------------------------

  abstract clusterHealth(): Promise<ClusterHealth>;

  abstract getState(url: string): Promise<string>;

  abstract info(): Promise<Overview>;

  // ---------------------------------------- 索引操作 ----------------------------------------

  abstract indices(): Promise<IndexItemResult>;

  abstract getIndex(index: string): Promise<IndexItem>;

  abstract createIndex(data: string): Promise<void>;

  abstract updateIndex(index: string, data: string): Promise<void>;

  abstract deleteBatchIndex(indexIds: Array<string>): Promise<void>;

  abstract addAlias(index: string, alias: string): Promise<string>;

  abstract removeAlias(index: string, alias: string): Promise<string>;

  // ---------------------------------------- 文档操作 ----------------------------------------

  abstract insertDoc(index: string, data: string, type?: string): Promise<string>;

  abstract updateDoc(index: string, id: string, data: string, type?: string): Promise<void>;

  abstract deleteBatchDoc(index: string, docIds: Array<string>, type?: string): Promise<void>;

  // ---------------------------------------- 搜索操作 ----------------------------------------

  abstract baseSearch(props: BaseSearchProp): Promise<BaseSearchResult>;

  abstract dataSearch(props: DataSearchProp): Promise<DataSearchResult>;

  abstract seniorSearch(props: SeniorSearchProp): Promise<string>;
}
